#include "Core\Oatmeal.h"			// standard library include (must be first include)
#include "Core\Internals.h"			// standard include for intenral definitions
#include "Core\Error.h"				// error handling routines
#include "IO\Settings.h"			// module to retrieve/set engine settings
#include "GUI\Windowing.h"			// standard windowing routines

////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// ENGINE SPECIFIC ROUTINES /////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

OATINLINE(tchar *)
apiGetCopyright (const tchar *szDest, const int32 nSize)
{
	// come back
	return NULL;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

OATINLINE(bool)
apiInitEngineFullscreen (const uint8 nBPP, const uint8 nVertRefresh, const tchar *szCompanyName,
						 const tchar *szAppName, const bool bSilentErrors, const bool bSingleInstance, const bool bOrthographic)
{
	bool bReturn = true;

	// note: only process the init routines on the first call of this function
	if(!GlobalSettings.bInitialized)
	{
		// first, wrap oatInitEngineWindowed() to acheive the rest of the functionality
		if(oatInitEngineWindowed(szCompanyName, szAppName, bSilentErrors, bSingleInstance, bOrthographic))
		{
			// set the BPP to use, but ensure it's A: in the range of 8-32 and B: a multipe of 8
			// if it does not meet this criteria, then don't set it and let the default value take
			if(((nBPP >= 8) && (nBPP <= 32)) && ((nBPP % 8) == 0))
				GlobalSettings.nBPP = nBPP;
			else
				bReturn = false;

			// perform a simple check to make sure the verticle refresh rate is within a range
			// normally considered to be valid, if not withint range let the default value take
			if((nVertRefresh >= 60) && (nVertRefresh <= 200))
				GlobalSettings.nVertRefresh = nVertRefresh;
			else
				bReturn = false;

			// flag that we wish to enter fullscreen mode, since this is an
			// important setting, only set if everything is a-ok so far
			if(bReturn)
				GlobalSettings.bFullscreen = true;
			else
			{
				// if we get here the either the BPP or vert refresh or both settings are invalid
				ShowErrorMessage(IDS_ERR_BPP_VERT);

				// the function we wrapped most likely set this to true, so
				// set it to false to indicate we still have bogus data
				GlobalSettings.bInitialized = false;
			}
		}
	}
	else
		bReturn = false;

	return bReturn;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

OATINLINE(bool)
apiInitEngineWindowed (const tchar *szCompanyName, const tchar *szAppName,
					   const bool bSilentErrors, const bool bSingleInstance, const bool bOrthographic)
{
	bool bReturn = true;

	// note: only process the init routines on the first call of this function
	if(!GlobalSettings.bInitialized)
	{
		// set the simple global properties
		GlobalSettings.bOrthographic = bOrthographic;
		GlobalSettings.bSilentErrors = bSilentErrors;
		GlobalSettings.bSingleInstance = bSingleInstance;

		// set the company name if passed (also check for an empty string)
		if((szCompanyName != NULL) && (szCompanyName[0] != _T('\0')))
			STRNCPY(GlobalSettings.szCompanyName, szCompanyName, MAX_SMALLSTRING - 1);

		// set the application name if passed (also check for an empty string)
		if((szAppName != NULL) && (szAppName[0] != _T('\0')))
			STRNCPY(GlobalSettings.szAppName, szAppName, MAX_SMALLSTRING - 1);
		else
		{
			ShowErrorMessage(IDS_ERR_APP_NAME);
			bReturn = false;
		}

		// set the flag to indicate the init routines should not be performed again
		if(bReturn) GlobalSettings.bInitialized = true;
	}
	else
		bReturn = false;

	return bReturn;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

OATINLINE(bool)
apiIsEngineRunning (void)
{
	static bool bReturn = true;

#ifdef _WIN32
	static MSG msg = {0};		// message struct for the queue

	/*/
	/ / NOTE: If you do not use a separate thread for rendering, it is imparative
	/ / that PeekMessage() is used rather than GetMessage(). But, it is just the
	/ / opposite if you do as it will save a bit of processing on this thread.
	/*/

	// remember, we treat the main window's existence to also mean the life of the app
	if(GlobalSettings.hMainWindow != NULL)
	{
		// check for the next unfiltered message on the queue
		// and make sure the engine has been initialized
		if(GetMessage(&msg, NULL, 0, 0) > 0)
		{
			// send the message off to the appropriate window procedure
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			// WM_QUIT was sent or we got an error, time to shutdown the engine
			DoPostWindowingCleanUp();
			bReturn = false;
		}
	}
	else
	{
		// only after we get here is it safe to find out why we have a problem
		// due to the fact that this routine will be called a lot
		if(!GlobalSettings.bInitialized)
			ShowErrorMessage(IDS_ERR_NO_INIT);
		else
			// this means the only reason left is the window just wasn't created
			ShowErrorMessage(IDS_ERR_NO_MAINWND);

		bReturn = false;
	}

#endif

	return bReturn;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////